home *** CD-ROM | disk | FTP | other *** search
- ;/* how to compile this thingy:
- gcc2 -s -O2 -mc68000 -DNDEBUG hunk2gcc.c -o hunk2gcc
- quit
- */
-
- /*
- * Convert amiga object files in the hunk format into a.out-object files.
- * ALINK style (ie. concatenated) libraries are supported as well, in that
- * case a collection of object files is generated, you'll have to run
- * `ar rs libfoo.a obj.*' on them to make an a.out-style library out of
- * them.
- *
- * Currently untested are:
- * o base-relative relocs and references
- * I'll first have to teach gnu-ld how to deal with them ;-)
- * o conversion of load files...
- * o common symbols, amiga objects normally don't use them, sigh
- *
- * Currently not implemented are:
- * o BLINK style indexed libraries (HUNK_LIB and HUNK_INDEX). If you're
- * generating such libraries yourself, you can as well generate oldstyle
- * libraries, and the libraries from Commodore-Amiga are in ALINK format
- * (amiga.lib and friends).
- * This index-format is so weird and complicated that I didn't bother
- * long to decide not to support it. If someone volunteers (you got
- * the source;-)) please send me enhancements!
- *
- * V1.0 91-10-08 M.Wild first hack
- * V1.01 92-01-20 M.Wild some pcrel code commented out, something is weird there..
- *
- * This is free software. This means that I don't care what you do with it
- * as long as you don't claim you wrote it. If you enhance it, please
- * send me your diffs!
- * Oh, of course, you use this stuff entirely at your own risk, I'm not
- * responsible for any damage this program might cause to you, your computer,
- * your data, your cat, your whateveryoucanthinkof, no warranty whatsoever is
- * granted.
- *
- * I can be reached on internet as: wild@nessie.cs.id.ethz.ch (Markus Wild)
- *
- */
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- /* sun3-a.out file */
- #include <a.out.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- /* This is really <dos/doshunks.h>, which is a 2.0 header file.
- * You can get those 2.0 headers from CATS.
- * Sorry, I'm not allowed to include them here. You may as well take the
- * AmigaDOS Manual 2nd ed. (you'll miss the a4-rel hunks) or 3rd ed. and write
- * the header yourself, it's not that long and difficult
- */
- #include "doshunks.h"
-
-
- #ifndef NDEBUG
- #define DP(a) printf a
- #else
- #define DP(a)
- #endif
-
-
- extern int errno;
-
- /* my favorite typedefs ;-)) */
- typedef unsigned char uchar;
- typedef unsigned long ulong;
-
- ulong *file_buf = 0;
-
- struct reloc {
- /* at which offset to relocate */
- int offset;
- /* based on which hunk base */
- int from_hunk, to_hunk;
- int size;
- int pcrel;
- int baserel;
- /* if != -1, the "to_hunk" field is not used */
- int sym_num;
- };
-
- /* NOTE: this symbol definition is compatible with struct nlist, and it will
- * be converted into a struct nlist in 'emit_aout_obj' */
- struct symbol {
- int name; /* string as offset into string table */
- uchar type;
- uchar pad1; /* really n_other */
- short hunk_num; /* really n_desc */
- ulong value;
- };
-
- struct table {
- void *base;
- int el_size;
- int i;
- int max_el;
- };
-
- void
- emit_aout_file (int fd, void *text, void *data, struct exec *hdr,
- struct table *ch_tab, struct table *dh_tab, struct table *bh_tab,
- struct table *reloc_tab, struct table *symbol_tab, int max_hunk);
-
- #define TAB_START_SIZE 1024
-
- /* advance the hunk-pointer to the next hunk. Assumes the hunk-pointer is
- * pointing at the length-field currently
- */
- static void inline
- next_hunk(ulong **hp)
- {
- /* skip over the length field and the there given length */
- *hp += 1 + **hp;
- }
-
- /****************************************************************************/
-
- /* these two function maintain the string table. You may only free the last
- * string allocated. (This could be done with an obstack as well, but I really
- * don't need the whole functionality of an obstack, so I kept it simple ;-))
- * Only use the offset, since the table itself may be reallocated.
- */
- char *str_table = 0;
- int strtab_size, strtab_index;
-
- static int inline
- stralloc (int len)
- {
- int res;
-
- /* always include the zero terminator */
- len++;
-
- if (! str_table)
- {
- strtab_size = TAB_START_SIZE;
- /* start the table at index 4, leaving space to later fill in the
- * size of the table */
- strtab_index = 4;
- str_table = malloc (strtab_size);
- }
-
- while (strtab_index + len > strtab_size)
- {
- strtab_size <<= 1;
- str_table = realloc (str_table, strtab_size);
- }
-
- res = strtab_index;
- strtab_index += len;
- return res;
- }
-
- static void inline
- strfree (int str)
- {
- strtab_index = str;
- }
-
- /****************************************************************************/
-
- static void inline
- add_table (struct table *tab, void *el)
- {
- if (tab->i == tab->max_el)
- {
- if (! tab->base)
- {
- tab->max_el = TAB_START_SIZE;
- tab->base = malloc (tab->max_el * tab->el_size);
- }
- else
- {
- tab->max_el <<= 1;
- tab->base = realloc (tab->base, tab->max_el * tab->el_size);
- }
- if (! tab->base)
- {
- fprintf (stderr, "Out of memory adding to table.\n");
- /* exit does close all outstanding files ;-) */
- exit (20);
- }
- }
- bcopy (el, (uchar *)tab->base + (tab->i++ * tab->el_size), tab->el_size);
- }
-
- static void inline
- add_reloc (struct table *tab, int from, int to, int offset,
- int size, int pcrel, int baserel, int sym_num)
- {
- struct reloc r;
-
- DP(("reloc: from=%d, to=%d, off=%d, size=%d, pc=%d, ba=%d, syn=%d\n",
- from, to, offset, size, pcrel, baserel, sym_num));
-
- r.from_hunk = from;
- r.to_hunk = to;
- r.offset = offset;
- r.size = size;
- r.pcrel = pcrel;
- r.baserel = baserel;
- r.sym_num = sym_num;
- add_table (tab, &r);
- }
-
- static void inline
- add_symbol (struct table *tab, int num, ulong type, int value, char *name)
- {
- struct symbol s;
-
- s.hunk_num = num;
- s.type = type >> 24;
- s.value = value;
- s.name = stralloc ((type & 0xffffff)<<2);
- bcopy (name, str_table+s.name, (type & 0xffffff)<<2);
- (str_table+s.name)[(type & 0xffffff)<<2] = 0;
-
- /* some (really stupid..) compilers mention symbols twice, once as
- * a definition, and once as an EXT_SYMB. So we really have to search
- * the symbol_table before adding an EXT_SYMB and check if a symbol of this name
- * isn't already defined for this value. If this hack should slow down
- * the conversion dramatically, I'll have to resort to hashing, I don't
- * like that idea... */
- if (s.type == EXT_SYMB)
- {
- int i;
-
- for (i = 0; i < tab->i; i++)
- /* we have CSE in the compiler, right? ;-)) */
- if (((struct symbol *)tab->base)[i].value == s.value &&
- ((struct symbol *)tab->base)[i].hunk_num == s.hunk_num &&
- ! strcmp (str_table+((struct symbol *)tab->base)[i].name,
- str_table+s.name))
- {
- strfree (s.name);
- return;
- }
- }
-
- add_table (tab, &s);
- }
-
- /****************************************************************************/
-
- void
- digest_objfile (ulong **file_pptr, ulong *max_fp)
- {
- /* this makes it less clumsy.. */
- ulong *file_ptr = *file_pptr;
- static int obj_file_num = 0;
- int units = 0;
- /* to be filled in by the hunk_unit name parameter */
- int fd = -1;
-
- /* buffer-pointers, where text, data & bss sections are stored.
- * Currently only one hunk with size!=0 of type text/data/bss each is
- * supported */
- uchar *text, *data;
- struct exec hdr;
-
- /* hunk numbers, needed to associate reloc blocks with segments */
- int hunk_num;
- static struct table code_hunks = { 0, 4, 0, 0 };
- static struct table data_hunks = { 0, 4, 0, 0 };
- static struct table bss_hunks = { 0, 4, 0, 0 };
-
- /* static so that no initialization code is required */
- static struct table reloc_tab = { 0, sizeof (struct reloc), 0, 0 };
- static struct table symbol_tab = { 0, sizeof (struct symbol), 0, 0 };
-
- /* (re) init tables */
- strtab_index = 4;
- code_hunks.i =
- data_hunks.i =
- bss_hunks.i =
- reloc_tab.i =
- symbol_tab.i = 0;
-
-
- while (units < 2)
- {
- switch (*file_ptr++)
- {
- case HUNK_UNIT:
- DP(("HUNK_UNIT: units = %d\n", units));
- if (units++) break;
- #if 0
- if (! file_ptr[0])
- #endif
- {
- /* need [], not *, so that gcc allocates a fresh copy for
- * mkstemp() to modify! */
- char tmp_nam[] = "obj.YYYY.XXXXXX";
- /* this trick makes mkstemp() lots faster ;-) */
- sprintf (tmp_nam, "obj.%04d.XXXXXX", obj_file_num++);
- if ((fd = mkstemp (tmp_nam)) < 0)
- fprintf (stderr, "Can't create object file: %s. Ignoring it.\n",
- tmp_nam, strerror (errno));
- }
- #if 0
- /* this idea was too good.. there are so many stupid (and duplicate!) names
- * of program units, that this generated ridiculous results... */
-
- else
- {
- char *file_name;
- file_name = alloca (file_ptr[0] + 1);
- strncpy (file_name, (char *)&file_ptr[1], file_ptr[0]);
- if ((fd = open (file_name, O_RDWR|O_CREAT|O_EXCL, 0666)) < 0)
- fprintf (stderr, "Can't create %s: %s. Ignoring it.\n",
- file_name, strerror (errno));
- }
- #endif
-
- /* init data for new object file */
- text = data = 0;
- bzero (&hdr, sizeof (hdr));
- /* if someone want's to use'em on a sun, why shouldn't we make
- * the files sun-conformant? */
- hdr.a_toolversion = TV_SUN2_SUN3;
- hdr.a_machtype = M_68010; /* not restricted to 68020 only */
- hdr.a_magic = OMAGIC; /* relocatable format */
- hunk_num = 0;
- next_hunk (& file_ptr);
- break;
-
- case HUNK_NAME:
- case HUNK_DEBUG:
- DP(("HUNK_NAME/DEBUG\n"));
- /* this hunk is silently ignored ;-) */
- next_hunk (& file_ptr);
- break;
-
- case HUNK_OVERLAY:
- fprintf (stderr, "warning: overlay hunk ignored!\n");
- next_hunk (& file_ptr);
- break;
-
- case HUNK_BREAK:
- fprintf (stderr, "warning: break hunk ignored!\n");
- break;
-
- case HUNK_HEADER:
- fprintf (stderr, "warning: load file header encountered.\n");
- fprintf (stderr, " are you sure this is an object file?\n");
- /* nevertheless, we go on. perhaps some day I need this feature to
- * be able to convert a loadfile into an object file?! */
-
- /* skip (never used) resident library names */
- while (file_ptr[0]) next_hunk (& file_ptr);
- /* skip null-word, table_size, F & L, and size-table */
- file_ptr += 4 + (file_ptr[1] - file_ptr[2] + 1);
- break;
-
- case HUNK_CODE:
- DP(("HUNK_CODE, size = $%x\n", file_ptr[0] << 2));
- if (file_ptr[0])
- {
- /* only accept one code hunk with size != 0 */
- if (hdr.a_text)
- fprintf (stderr, "only one code hunk with size!=0 supported.\n");
- else
- {
- text = (uchar *)&file_ptr[1];
- hdr.a_text = file_ptr[0] << 2;
- }
- }
- next_hunk (& file_ptr);
- add_table (& code_hunks, &hunk_num);
- hunk_num++;
- break;
-
- case HUNK_DATA:
- DP(("HUNK_DATA, size = $%x\n", file_ptr[0] << 2));
- if (file_ptr[0])
- {
- /* only accept one data hunk with size != 0 */
- if (hdr.a_data)
- fprintf (stderr, "only one data hunk with size!=0 supported.\n");
- else
- {
- data = (uchar *)&file_ptr[1];
- hdr.a_data = file_ptr[0] << 2;
- }
- }
- next_hunk (& file_ptr);
- add_table (& data_hunks, & hunk_num);
- hunk_num++;
- break;
-
- case HUNK_BSS:
- DP(("HUNK_BSS, size = $%x\n", file_ptr[0] << 2));
- if (file_ptr[0])
- {
- /* only accept one bss hunk with size != 0 */
- if (hdr.a_bss)
- fprintf (stderr, "only one bss hunk with size!=0 supported.\n");
- else
- hdr.a_bss = file_ptr[0] << 2;
- }
- file_ptr++;
- add_table (& bss_hunks, & hunk_num);
- hunk_num++;
- break;
-
- case HUNK_RELOC8:
- case HUNK_RELOC16:
- case HUNK_RELOC32:
- /* do they work like this? don't know... */
- case HUNK_DREL8:
- case HUNK_DREL16:
- case HUNK_DREL32:
- {
- int size, brel;
-
- brel = file_ptr[-1] >= HUNK_DREL32;
- size = (brel ? HUNK_DREL8 : HUNK_RELOC8) - file_ptr[-1];
- DP(("HUNK_RELOC/DREL ($%x), brel = %d, size = %d\n", file_ptr[-1], brel, size));
-
- while (file_ptr[0])
- {
- long to_reloc = file_ptr[1];
- long n = file_ptr[0];
-
- while (n--)
- /* amiga relocs are automatically pcrel, when size < 2
- * according to the AmigaDOS-Manual 2nd ed. */
- add_reloc (&reloc_tab, hunk_num-1, to_reloc, file_ptr[n+2],
- size, size != 2, brel, -1);
-
- file_ptr += file_ptr[0] + 2;
- }
- }
- file_ptr++;
- break;
-
- case HUNK_SYMBOL:
- case HUNK_EXT:
- DP(("HUNK_SYMBOL/EXT\n"));
- while (file_ptr[0])
- {
- int n, size, brel;
-
- DP((" EXT_: %d, %-*.*s\n", file_ptr[0] >> 24,
- 4*(file_ptr[0] & 0xffffff), 4*(file_ptr[0] & 0xffffff), &file_ptr[1]));
-
- switch (file_ptr[0] >> 24)
- {
- case EXT_SYMB:
- case EXT_DEF:
- case EXT_ABS:
- case EXT_RES:
- add_symbol (&symbol_tab, hunk_num-1, file_ptr[0],
- file_ptr[1+(file_ptr[0] & 0xffffff)],
- (char *)&file_ptr[1]);
- file_ptr += 2+(file_ptr[0] & 0xffffff);
- break;
-
- case EXT_COMMON:
- /* first define the common symbol, then add the relocs */
- add_symbol (&symbol_tab, hunk_num-1, file_ptr[0],
- file_ptr[1+(file_ptr[0] & 0xffffff)],
- (char *)&file_ptr[1]);
- file_ptr += 2+(file_ptr[0] & 0xffffff);
-
- /* now the references, translated into relocs */
- for (n = file_ptr[0]; n--; )
- add_reloc (&reloc_tab, hunk_num - 1, -1, file_ptr[n],
- 2, 0, 0, symbol_tab.i - 1);
- next_hunk (&file_ptr);
- break;
-
- case EXT_REF8:
- case EXT_REF16:
- case EXT_REF32:
- case EXT_DEXT8:
- case EXT_DEXT16:
- case EXT_DEXT32:
- size = file_ptr[0] >> 24;
- brel = size >= EXT_DEXT32;
- size = (size == EXT_REF32 || size == EXT_DEXT32) ? 2 :
- ((size == EXT_REF16 || size == EXT_DEXT16) ? 1 : 0);
- /* first define the symbol (as undefined ;-)),
- * then add the relocs */
- add_symbol (&symbol_tab, hunk_num-1, file_ptr[0],
- 0, (char *)&file_ptr[1]);
- file_ptr += 1+(file_ptr[0] & 0xffffff);
-
- /* now the references, translated into relocs */
- for (n = file_ptr[0]; n; n--)
- add_reloc (&reloc_tab, hunk_num - 1, -1, file_ptr[n],
- size, size < 2, brel, symbol_tab.i - 1);
- next_hunk (&file_ptr);
- break;
-
- default:
- fprintf (stderr,
- "Unknown symbol type %d, don't know how to handle!\n",
- file_ptr[0] >> 24);
- /* can't continue, don't know how much to advance the file_ptr
- * to reach the next valid hunk/block */
- exit(20);
- }
- }
- file_ptr++;
- break;
-
- case HUNK_END:
- DP(("HUNK_END\n"));
- break;
-
- default:
- fprintf (stderr, "Unknown hunk type $%x, unit offset = $%x.\n",
- file_ptr[-1], ((file_ptr-1)-*file_pptr) * 2);
- /* can't continue, don't know how much to advance the file_ptr
- * to reach the next valid hunk/block */
- exit(20);
- }
-
- if (file_ptr >= max_fp) break;
- }
-
- *file_pptr = file_ptr >= max_fp ? max_fp : file_ptr-1;
-
- if (fd != -1)
- emit_aout_file (fd, text, data, & hdr,
- & code_hunks, & data_hunks, & bss_hunks,
- & reloc_tab, & symbol_tab, hunk_num);
- }
-
-
- void
- emit_aout_file (int fd, void *text, void *data, struct exec *hdr,
- struct table *ch_tab, struct table *dh_tab, struct table *bh_tab,
- struct table *reloc_tab, struct table *symbol_tab, int max_hunk)
- {
- int *code_hunks = ch_tab->base;
- int *data_hunks = dh_tab->base;
- int *bss_hunks = bh_tab->base;
- char htype[max_hunk];
- int i;
- struct reloc *r;
- struct symbol *s;
- static struct table text_relocs = { 0, sizeof (struct reloc_info_68k), 0, 0 };
- static struct table data_relocs = { 0, sizeof (struct reloc_info_68k), 0, 0 };
-
- text_relocs.i =
- data_relocs.i = 0;
-
- /* convert hunk-numbers into N_TEXT,N_DATA,N_BSS types */
- for (i = 0; i < ch_tab->i; i++) htype[code_hunks[i]] = N_TEXT;
- for (i = 0; i < dh_tab->i; i++) htype[data_hunks[i]] = N_DATA;
- for (i = 0; i < bh_tab->i; i++) htype[bss_hunks[i]] = N_BSS;
-
- /* first conversion run. Change all hunk-numbers into N_TEXT, N_DATA and
- * N_BSS rsp.
- * (If you wanted to support multi-hunk files (ie. files with more than
- * one code/data/bss hunk with size > 0) you'd want to do the necessary
- * conversions here.)
- */
- for (i = 0, r = (struct reloc *)reloc_tab->base; i < reloc_tab->i; i++, r++)
- {
- r->from_hunk = htype[r->from_hunk];
- if (r->to_hunk > -1)
- r->to_hunk = htype[r->to_hunk];
- }
- for (i = 0, s = (struct symbol *)symbol_tab->base; i < symbol_tab->i; i++, s++)
- s->hunk_num = htype[s->hunk_num];
-
- /* now convert the symbols into nlist's */
- for (i = 0, s = (struct symbol *)symbol_tab->base; i < symbol_tab->i; i++, s++)
- {
- int nl_type = 0;
-
- switch (s->type)
- {
- case EXT_DEF:
- /* externally visible symbol */
- nl_type = N_EXT;
- /* fall into */
-
- case EXT_SYMB:
- nl_type |= s->hunk_num;
- /* adjust DATA and BSS values to the one-seg model */
- if (s->hunk_num == N_DATA)
- s->value += hdr->a_text;
- if (s->hunk_num == N_BSS)
- s->value += hdr->a_text + hdr->a_data;
- break;
-
- case EXT_ABS:
- nl_type = N_ABS | N_EXT;
- break;
-
- case EXT_COMMON:
- /* ok for common as well, because the value field is only setup
- * for common-symbols */
-
- case EXT_REF32:
- case EXT_REF16:
- case EXT_REF8:
- case EXT_DEXT32:
- case EXT_DEXT16:
- case EXT_DEXT8:
- nl_type = N_UNDF | N_EXT;
- break;
-
- default:
- fprintf (stderr, "What kind of symbol is THAT? (%d)\n", s->type);
- break;
- }
-
- s->type = nl_type;
- s->pad1 = s->hunk_num = 0; /* clear nl_other & nl_desc fields */
- }
-
- /* now convert the reloc table. Adjust (like above) data/bss values to the
- * one-segment model for local relocations */
- for (i = 0, r = (struct reloc *)reloc_tab->base; i < reloc_tab->i; i++, r++)
- {
- struct reloc_info_68k rel;
- uchar *core_addr;
-
- rel.r_address = r->offset;
- core_addr = (r->from_hunk == N_TEXT) ? text : data;
-
- if (r->to_hunk == N_DATA)
- if (r->size == 2)
- *(ulong *)(core_addr + rel.r_address) += hdr->a_text;
- else
- fprintf (stderr, "%s reloc into N_DATA, what should I do?\n",
- r->size == 1 ? "Short" : "Byte");
- else if (r->to_hunk == N_BSS)
- if (r->size == 2)
- *(ulong *)(core_addr + rel.r_address) += hdr->a_text + hdr->a_data;
- else
- fprintf (stderr, "%s reloc into N_BSS, what should I do?\n",
- r->size == 1 ? "Short" : "Byte");
-
- #if 0
- /* don't know, what went wrong, but this conversion surely converts
- * _LVO calls wrong. I'm sure leaving this out will generate other bugs..
- * sigh... */
-
- /* hmm... amigadog-hunks seem to do this in a strange way...
- * Those relocs *are* treated as pcrel relocs by the linker (blink),
- * but they're not setup as such... geez, this hunk format.. */
- if (r->pcrel)
- switch (r->size)
- {
- case 2:
- *(long *)(core_addr + rel.r_address) -= rel.r_address;
- break;
-
- case 1:
- *(short *)(core_addr + rel.r_address) -= rel.r_address;
- break;
-
- case 0:
- *(char *)(core_addr + rel.r_address) -= rel.r_address;
- break;
- }
- #endif
-
- rel.r_symbolnum = r->sym_num > -1 ? r->sym_num : r->to_hunk;
- rel.r_pcrel = r->pcrel;
- rel.r_length = r->size;
- rel.r_extern = r->sym_num > -1;
- rel.r_baserel = r->baserel;
- rel.r_jmptable = rel.r_relative = 0;
-
- DP(("r68: %s reloc\n", (r->from_hunk == N_TEXT) ? "text" : "data"));
- add_table ((r->from_hunk == N_TEXT) ? & text_relocs : & data_relocs,
- &rel);
- }
-
- DP(("r68: #tr = %d, #dr = %d\n", text_relocs.i, data_relocs.i));
-
- /* oky, fill out the rest of the header and dump everything */
- hdr->a_syms = symbol_tab->i * sizeof (struct nlist);
- hdr->a_trsize = text_relocs.i * sizeof (struct reloc_info_68k);
- hdr->a_drsize = data_relocs.i * sizeof (struct reloc_info_68k);
- *(ulong *)str_table = strtab_index;
- write (fd, (char *)hdr, sizeof (*hdr));
- if (hdr->a_text) write (fd, text, hdr->a_text);
- if (hdr->a_data) write (fd, data, hdr->a_data);
- if (hdr->a_trsize) write (fd, text_relocs.base, hdr->a_trsize);
- if (hdr->a_drsize) write (fd, data_relocs.base, hdr->a_drsize);
- if (hdr->a_syms) write (fd, symbol_tab->base, hdr->a_syms);
- write (fd, str_table, strtab_index);
- close (fd);
- }
-
-
-
- int
- main (int argc, char *argv[])
- {
- struct stat stb;
- int ret_val = 0;
- ulong *obj_pointer;
-
- FILE *fp;
-
- /* loop over all arguments. Can be either
- * o object files
- * o libraries (ALINK style for now)
- */
- while (*++argv)
- {
- if (stat (*argv, &stb) == -1)
- {
- fprintf (stderr, "%s: %s\n", *argv, strerror (errno));
- continue;
- }
-
- file_buf = file_buf ? realloc (file_buf, stb.st_size)
- : malloc (stb.st_size);
- if (! file_buf)
- {
- fprintf (stderr, "%s: can't allocate %d byte of memory.\n",
- *argv, stb.st_size);
- ret_val = 20;
- break;
- }
-
- if (!(fp = fopen (*argv, "r")))
- {
- fprintf (stderr, "Can't open %s: %s.\n", *argv, strerror (errno));
- continue;
- }
-
- /* read the file in at once */
- if (fread (file_buf, stb.st_size, 1, fp) != 1)
- {
- fprintf (stderr, "Can't read %s: %s.\n", *argv, strerror (errno));
- fclose (fp);
- continue;
- }
-
- /* oky, now digest the file (possibly more than one object file) */
- for (obj_pointer = file_buf;
- obj_pointer < (ulong *)((uchar *)file_buf + stb.st_size); )
- digest_objfile (&obj_pointer, (ulong *)((uchar *)file_buf + stb.st_size));
-
- fclose (fp);
- }
-
- return ret_val;
- }
-